package com.hyt.it.ogt.controller.ykcj.zs;

import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hyt.check.CheckUtil;
import com.hyt.check.ruler.summary.ObjRuler;
import com.hyt.check.ruler.summary.StrRuler;
import com.hyt.common.apiInfor.ApiResponse;
import com.hyt.core.util.FastJsonUtil;
import com.hyt.it.ogt.common.config.ApiVersionConstant;
import com.hyt.it.ogt.controller.base.BaseController;
import com.hyt.it.ogt.ykcj.common.constant.Constants;
import com.hyt.it.ogt.ykcj.common.core.domain.AjaxResult;
import com.hyt.it.ogt.ykcj.common.enums.zs.CertificateProvideStatusEnums;
import com.hyt.it.ogt.ykcj.common.enums.zs.IdentificationType;
import com.hyt.it.ogt.ykcj.domain.zs.ZsTemplateConfig;
import com.hyt.it.ogt.ykcj.domain.zs.vo.ZsExamineeInfoVO;
import com.hyt.it.ogt.ykcj.service.zs.IZsExamineeInfoService;
import com.hyt.it.ogt.ykcj.utils.RedisLock;
import com.hyt.loginfo.model.User;
import com.hyt.loginfo.service.IBaseLoginService;
import com.hyt.model.PageParam;
import com.hyt.swagger.ApiVersion;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiOperationSort;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiSort;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description:
 * @Author: STARF
 * @CreateDate: 2022/06/24 11:11
 **/
@Api(tags = "zs.3.考生证书管理", value = "考生证书控制器")
@ApiSort(value = 403)
@Slf4j
@RestController
@RequestMapping("/examinee")
public class ExamineesController extends BaseController {

    @Resource
    private IZsExamineeInfoService iZsExamineeInfoService;
    @Resource
    private IBaseLoginService baseLoginService;
    @Resource
    private RedisLock redisLock;


    @ApiOperation(value = "分页获取证书管理列表",
            notes = "20000:成功;", response = ZsExamineeInfoVO.class)
    @ApiOperationSort(value = 1)
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "zsId", value = "证书id", dataType = "string", paramType = "query", required = true
            ),
            @ApiImplicitParam(
                    name = "idWords", value = "证件号、姓名", dataType = "string", paramType = "query", required = false
            ),
            @ApiImplicitParam(
                    name = "status", value = "证书状态：0-全部(可不传)，1-已颁发，2-未颁发\")", dataType = "Integer", paramType = "query", required = false
            ),
            @ApiImplicitParam(
                    name = "current", value = "分页查询每页条数", dataType = "string", paramType = "query", required = true
            ),
            @ApiImplicitParam(
                    name = "size", value = "分页查询当前页码", dataType = "string", paramType = "query", required = true
            )
    })
    @ApiVersion(group = ApiVersionConstant.V2_4_9)
    @GetMapping("/examineePage")
    public ApiResponse<Page<ZsExamineeInfoVO>> examineePage(String zsId,
                                                            String idWords,
                                                            Integer status,
                                                            Integer current,
                                                            Integer size) {
        // 获取当前登录人用户信息
        User user = baseLoginService.getSysUser();
        if (null == user || StringUtils.isEmpty(user.getId())) {
            return ApiResponse.<Page<ZsExamineeInfoVO>>builder().code(52411101).build();
        }
        startPage();
        PageParam<ZsExamineeInfoVO> pageParam = new PageParam<ZsExamineeInfoVO>();
        pageParam = iZsExamineeInfoService.examineePage(pageParam, zsId, idWords, status);
        return ApiResponse.<Page<ZsExamineeInfoVO>>builder().code(20000).data(pageParam).build();
    }


    @ApiOperation(value = "删除考生证书",
            notes = "20000:成功;")
    @ApiOperationSort(value = 2)
    @ApiVersion(group = ApiVersionConstant.V2_4_2)
    @GetMapping("/deleteExaminee")
    public ApiResponse<Object> deleteExaminee(@ApiParam(value = "考生证书id") @RequestParam String id) {
        String userId = baseLoginService.getUserId();
        return ApiResponse.builder().code(20000).data(iZsExamineeInfoService.deleteExaminee(id, userId)).build();
    }


    @ApiOperation(value = "证书查询", notes = "20000:成功;", response = ZsExamineeInfoVO.class)
    @ApiOperationSort(value = 3)
    @ApiVersion(group = ApiVersionConstant.V2_4_2)
    @GetMapping("/queryZsExaminee")
    public ApiResponse<Object> queryZsExaminee(
            @ApiParam(value = "姓名") @RequestParam String name,
            @ApiParam(value = "证件号码") @RequestParam String idCardNo,
            @ApiParam(value = "证件id") @RequestParam String zsId) throws Exception {
        ZsExamineeInfoVO vo = iZsExamineeInfoService.queryZsExaminee(zsId, name, idCardNo);
        return ApiResponse.builder().code(20000).data(vo).build();
    }


    @ApiOperation(
            value = "发放证书",
            notes = "20000:成功;"
    )
    @ApiOperationSort(value = 4)
    @ApiVersion(group = ApiVersionConstant.V2_4_2)
    @GetMapping("/issueCertificate")
    public AjaxResult issueCertificate(@ApiParam(value = "考生ID") @RequestParam String examineeInfoId) throws Exception {
        // 获取证书发放锁
        String key = Constants.LOCK_KEY_HEAD + examineeInfoId;
        String consumerId = UUID.randomUUID().toString();
        Boolean issueResult = redisLock.tryLock(key, consumerId, Constants.LOCK_TIME, () -> {
            return iZsExamineeInfoService.issueCertificate(examineeInfoId);
        }, "证书正在发放，请等待数据处理完成！");
        if (issueResult) {
            redisLock.unLock(key, consumerId);
        }
        return AjaxResult.success(issueResult);
    }

    @SuppressWarnings("unchecked")
    @ApiOperation(value = "考生证书信息修改", notes = "20000:成功;")
    @ApiOperationSort(value = 5)
    @ApiVersion(group = ApiVersionConstant.V2_4_2)
    @PostMapping("/editCertificate")
    public AjaxResult editCertificate(@ApiParam(value = "考生信息") @RequestBody ZsExamineeInfoVO zsExamineeInfoVO) throws Exception {
        log.debug("# 考生证书信息修改请求参数：{}", FastJsonUtil.getBeanToJson(zsExamineeInfoVO));
        // 业务基础数据校验
        CheckUtil.check(zsExamineeInfoVO, ObjRuler.notNull(52402501, "参数信息不完整"))
                .check(zsExamineeInfoVO.getId(), StrRuler.notEmpty(52402501, "参数信息不完整"))
                .check(zsExamineeInfoVO.getZsId(), StrRuler.notEmpty(52402501, "参数信息不完整"))
                .check(zsExamineeInfoVO.getExamineeName(), StrRuler.notEmpty(52402502, "考生姓名不能为空"))
                .check(zsExamineeInfoVO.getExamineeSex(), StrRuler.notEmpty(52402503, "考生性别不能为空"))
                .check(zsExamineeInfoVO.getIdentificationType(), StrRuler.notEmpty(52402504, "证件类型不能为空"))
                .check(zsExamineeInfoVO.getIdentificationNo(), StrRuler.notEmpty(52402505, "证件号码不能为空"))
                .check(zsExamineeInfoVO.getIdentificationNo(), IdentificationType.getRulerByCode(zsExamineeInfoVO.getIdentificationType()).fail(52402513, "证件号码不合法"))
                .check(zsExamineeInfoVO.getCertificateSubject(), StrRuler.notEmpty(52402506, "证书专业不能为空"))
                .check(zsExamineeInfoVO.getCertificateLevel(), StrRuler.notEmpty(52402507, "证书等级不能为空"))
                .check(zsExamineeInfoVO.getCertificateSerialNumber(), StrRuler.notEmpty(52402508, "证书编号不能为空"))
                .check(zsExamineeInfoVO.getCertificateSerialNumber(), "证书编号", StrRuler.lengthLte(20).failCode(52402514));

        // 数据证书编号是不是重复
        Boolean exitCertificateSerialNumber = iZsExamineeInfoService.exitCertificateSerialNumber(zsExamineeInfoVO.getZsId(), zsExamineeInfoVO.getId(), zsExamineeInfoVO.getCertificateSerialNumber());
        if (exitCertificateSerialNumber) {
            return AjaxResult.error(52402509, "已存在相同证书编码，请调整！");
        }

        // 校验证件类型是不是重复
        Boolean exitIdentificationNo = iZsExamineeInfoService.exitIdentificationNo(zsExamineeInfoVO.getZsId(), zsExamineeInfoVO.getId(), zsExamineeInfoVO.getIdentificationType(),
                zsExamineeInfoVO.getIdentificationNo());
        if (exitIdentificationNo) {
            return AjaxResult.error(52402510, "已存在相同身份证号码，请调整！");
        }

        // 校验考生证书是不是已经发放
        Boolean checkCertificateProvideStatus = iZsExamineeInfoService.checkCertificateProvideStatus(zsExamineeInfoVO.getZsId(), zsExamineeInfoVO.getId(), CertificateProvideStatusEnums.PROVIDED.getCode());
        if (checkCertificateProvideStatus) {
            return AjaxResult.error(52402511, "考生证书已经发放不允许修改！");
        }

        Boolean editResult = iZsExamineeInfoService.editZsExamineeInfo(zsExamineeInfoVO);
        if (!editResult) {
            return AjaxResult.error(52402512, "编辑考生证书失败");
        } else {
            return AjaxResult.success("编辑考生证书成功");
        }
    }


    @ApiOperation(value = "获取考生证书详情", notes = "20000:成功;")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "id", value = "考生证书主键id", dataType = "string", paramType = "query", required = true
            ),
            @ApiImplicitParam(
                    name = "zsId", value = "考生证书id", dataType = "string", paramType = "query", required = true
            )
    })
    @ApiOperationSort(value = 6)
    @ApiVersion(group = ApiVersionConstant.V2_4_2)
    @GetMapping("/getCertificateDetail")
    public AjaxResult getCertificateDetail(String id, String zsId) throws Exception {
        // 获取证书详情
        ZsExamineeInfoVO zsExamineeInfoVO = iZsExamineeInfoService.queryZsExamineeById(id, zsId);
        return AjaxResult.success("查询考生证书详情成功", zsExamineeInfoVO);
    }

    @ApiOperation(
            value = "取消发放证书",
            notes = "20000:成功;",
            response = Boolean.class
    )
    @ApiOperationSort(value = 7)
    @ApiVersion(group = ApiVersionConstant.V2_4_2)
    @GetMapping("/recallCertificate")
    public AjaxResult recallCertificate(@ApiParam(value = "考生ID") @RequestParam String examineesInfoId) throws Exception {
        return AjaxResult.success(iZsExamineeInfoService.recallCertificate(examineesInfoId));
    }

    @ApiOperation(
            value = "获取模板列表渲染配置",
            notes = "20000:成功;",
            response = ZsTemplateConfig.class
    )
    @ApiOperationSort(value = 8)
    @ApiVersion(group = ApiVersionConstant.V2_4_9)
    @GetMapping("/showViewHead")
    public AjaxResult showViewHead(@ApiParam(value = "证书ID") @RequestParam String zsId) {
        return AjaxResult.success(iZsExamineeInfoService.showViewHead(zsId));
    }
}
